import json
from typing import List

from re_common.baselibrary.utils.core.mdeprecated import try_except2, try_except2_async

from apps.crawler_platform.core_callback import *
# 不执行逻辑，目的是为了不让 from apps.crawler_platform.core_callback import *
# 被编辑器认为没有使用，快捷清除时就不会被清除
from apps.crawler_platform.core_platform.core_controller import CoreConterollerMixin
from apps.crawler_platform.core_platform.core_g import SQLTable
from apps.crawler_platform.core_platform.core_sql import CoreSqlMixin
from apps.crawler_platform.core_platform.g_model import DownModel, PageHtmlModel, HtmlModel, PaperDaysModel, \
    DealItemModel, DealInsertModel, DealItemNextModel, DealUpdateModel, PaperPageModel, PaperArticleModel
from apps.crawler_platform.paper_platform.base_qk_step import BaseQKItems, BaseQKStep

STATICA_HACK = False
# globals()['kcah_acitats'[::-1].upper()] = False
if STATICA_HACK:  # pragma: no cover
    null()


class PaperArticleItems(BaseQKItems):

    def __init__(self):
        super(PaperArticleItems, self).__init__()
        self.rawid = ""

    def get_pkm(self):
        """
        获取主键
        :return:
        """
        return {"task_name": self.task_name,
                "task_tag": self.task_tag,
                "rawid": self.rawid,
                }

    def set_downmodel(self):
        self.down_model = DownModel[HtmlModel](down_dict={})


class PaperArticleDownStep(BaseQKStep, CoreConterollerMixin):

    def __init__(self, request, inputs):
        super().__init__()

        self.err_tag = "PaperArticle"

        self.pm = PaperArticleItems()
        self.pm.set_downmodel()
        self.input = inputs
        self.pm.task_name = inputs.data.task_name
        self.pm.task_tag = inputs.data.task_tag
        self.pm.rawid = inputs.data.rawid

        self.pm.redis = request.app.state.redis

        self.request = request
        self.step_info = ""
        # 解析字段字典
        self.para_dicts = {}

        self.sql_model: PaperArticleModel

    @try_except2()
    def verify_html(self):
        """
        验证html
        """
        return True, {}

    @try_except2_async(is_print=True)
    async def deal_html(self):
        return await super().deal_html(PaperArticleModel)

    @try_except2()
    def verify_para(self):
        """
        验证解析出来的数据
        """
        return True, ""

    @try_except2_async(is_print=True)
    async def save_sql(self, type="", code=""):
        """
        与关系型sql的处理 包括存储下一级的sql以及本级sql的状态和字段更新
        """
        if type != "":
            return await super().save_sql(SQLTable.paper_article, type, code)
            # where = self.pm.get_pkm()
            # vv = self.pm.get_sql_state()
            # update_no_placeholder = self.pm.get_update_no_placeholder()
            # if vv or update_no_placeholder:
            #     bools, dicts = await CoreSqlMixin.update_sql(SQLTable.paper_article, vv, update_no_placeholder, where)
            #     self.pm.set_sql_state({}, is_update=False)
            #     self.pm.set_update_no_placeholder({}, is_update=False)
            #     return bools, dicts
            # else:
            #     return True, {}
        # befor 操作
        befor_deal_item_model: DealItemModel = self.deal_model.befor_dicts
        insert_list: List[DealInsertModel] = befor_deal_item_model.insert
        for insert in insert_list:
            lists: List[dict] = insert.lists
            insert_pre: str = insert.insert_pre
            if lists:
                list_v = []
                list_key = list(lists[0].keys())
                for item in lists:
                    list_v.append(tuple(item.values()))
                bools, dicts = await CoreSqlMixin.insert_many_sql(
                    SQLTable.paper_page, list_key, list_v,
                    insert=insert_pre)
                if not bools:
                    return bools, dicts

        update: dict = befor_deal_item_model.update
        update_no_placeholder: dict = befor_deal_item_model.update_no_placeholder
        if update or update_no_placeholder:
            where = self.pm.get_pkm()
            bools, dicts = await CoreSqlMixin.update_sql(SQLTable.paper_article, update, update_no_placeholder,
                                                         where)
            if not bools:
                return bools, dicts
        # next操作
        next_deal_item_model: DealItemNextModel = self.deal_model.next_dicts
        insert_list: List[DealInsertModel] = next_deal_item_model.insert
        for insert in insert_list:
            lists: List[dict] = insert.lists
            insert_pre: str = insert.insert_pre
            if lists:
                list_v = []
                list_key = list(lists[0].keys())
                for item in lists:
                    list_v.append(tuple(item.values()))
                bools, dicts = await CoreSqlMixin.insert_many_sql(
                    SQLTable.paper_article, list_key, list_v,
                    insert=insert_pre)
                if not bools:
                    return bools, dicts

        update_list: List[DealUpdateModel] = next_deal_item_model.update_list
        for update_item in update_list:
            update_no_placeholder: dict = update_item.update_no_placeholder
            update = update_item.update
            where = update_item.where
            bools, dicts = await CoreSqlMixin.update_sql(SQLTable.paper_article, update,
                                                         update_no_placeholder,
                                                         where)
            if not bools:
                return bools, dicts

        # other_dicts
        other_dicts = self.deal_model.other_dicts
        where = self.pm.get_pkm()
        vv = {"other_dicts": json.dumps(other_dicts, ensure_ascii=False)}
        bools, dicts = await CoreSqlMixin.update_sql(SQLTable.paper_article, vv, {}, where)
        if not bools:
            return bools, dicts
        # null_dicts
        null_dicts = self.deal_model.null_dicts
        where = self.pm.get_pkm()
        vv = {"null_dicts": json.dumps(null_dicts, ensure_ascii=False)}
        bools, dicts = await CoreSqlMixin.update_sql(SQLTable.paper_article, vv, {}, where)
        if not bools:
            return bools, dicts
        # state
        # CoreSqlMixin.set_state(self.pm)

        vv = self.pm.get_sql_state()

        update_no_placeholder = self.pm.get_update_no_placeholder()
        where = self.pm.get_pkm()
        if vv or update_no_placeholder:
            bools, dicts = await CoreSqlMixin.update_sql(SQLTable.paper_article, vv, update_no_placeholder, where)
            if bools and vv["state"] == 0:
                return False, {"msg": "执行sql成功，但翻页没有完成"}
            return bools, dicts
        else:
            return True, {"msg": "没有执行最后的更新sql"}

    @try_except2_async(is_print=True)
    async def get_sql(self):
        row = await CoreSqlMixin.get_paper_article(self.pm.task_name, self.pm.task_tag,
                                                self.pm.rawid)
        if row:
            self.pm.sql_model = PaperArticleModel.parse_obj(row)
            return True, row
        else:
            return False, "sql查询不存在"

    @try_except2_async(is_print=True)
    async def save_nosql_html(self):
        bools, dicts = await super().save_nosql_html()
        return bools, dicts

    @try_except2_async(is_print=True)
    async def run_task(self):
        bools, err_info = await self.task_step()
        return bools, err_info

    async def my_task(self, table=""):
        """
        接入调用的task
        :return:
        """
        return await super().my_task(SQLTable.paper_article)
